﻿package test;
import java.util.ArrayList;
import java.util.LinkedList;

public class Calculator {

	static class Stack<T> {
		private LinkedList<T> storage = new LinkedList<T>();

		public void push(T v) {
			storage.addFirst(v);
		}
	        
		public T peek() {
			return storage.getFirst();
		}

		public T pop() {
			return storage.removeFirst();
		}

		public boolean empty() {
			return storage.isEmpty();
		}
	}
	static String formula;
	static Fraction result;
	public Fraction Calculator(String formula){
		this.formula=formula;
		return Calculator();
	}
	private static Fraction Calculator() {
		
		//在这里写一个根据式子（字符串formula）写出计算结果（Fraction（分数形式））
		//加油！可以随便加测试的东西（最后删掉就好了）
		return result;
	}
	public static void main(String args[]) {
		Stack<String> sign = new Stack<String>();
		ArrayList<Double> value = new ArrayList<Double>();
		char[] array = formula.toCharArray();// 选取什么样的容器存放String比较合适需要考虑；
		// System.out.println(array);
		ArrayList<String> numberStr = new ArrayList<String>();
		ArrayList<Double> numberDou = new ArrayList<Double>();
		// System.out.println("1"+array.toString());
		double num = 0.0, res = 0.0;// 考虑到数值可能为两位；
		//int mark = 0;// 标志当前的符号是否为sin,cos，可直接进行计算；运算标志
		int i = 0;
		try {
			for (i = 0; i < array.length; i++) {
				for (int k = i; k < array.length && array[k] >= '0'
						&& array[k] <= '9'; k++, i++) {
					String tmpString = array[i] + "";
					//System.out.println(tmpString);
					numberStr.add(tmpString);// 不能强制转换为double，原本的number为double类型的，因此char型的array不能直接
					// 在前面加double强制转换
				}

				if (numberStr.size() > 0) {// 通过判断存放数值的数组大小间接判断是否为数字；
					num = 0;
					for (String string : numberStr) {
						numberDou.add(Double.parseDouble(string));
					}
					for (int j = numberDou.size() - 1; j >= 0; j--) {
						num += numberDou.get(j)* Math.pow(10, (numberDou.size() - j - 1));// 超出范围的错误，number.get(j)改为j-1
						// System.out.println(num);
					}
					value.add(num);
					//System.out.println("num:" + num);
					numberStr.clear();
					numberDou.clear();
					i--;
				} else {
					
					if (array[i] == '(') {
						sign.push("(");
					} else if (array[i] == ')') {
						while (sign.peek() != "(") {
							num = Calculate(value, sign.pop(), value
									.remove(value.size() - 1));
							value.add(num);// (90*(sin90-1)-66)/7
						}
						sign.pop();
					} else if (array[i] == '+' || array[i] == '-'
							|| array[i] == '*' || array[i] == '/'
							|| array[i] == '^') {
						// 加上现有的符号

						// 如果栈非空，且栈顶的运算符优先级比小于等于入栈的运算符优先级，则一直出栈并计算
						while (!sign.empty()) {
							if (compare(array[i] + "", sign.peek()) == 1) {
								break;
							} else {
								num = Calculate(value, sign.pop(), value
										.remove(value.size() - 1));
								value.add(num);
							}
						}

						sign.push(array[i] + "");
					}
				}

			}

			// 如果栈为非空的话，则继续计算
			while (!sign.empty()) {
				res = Calculate(value, sign.pop(), value
						.remove(value.size() - 1));
				value.add(res);
			}

			// 如果出来的结果太小了，则直接赋值为0
			res = value.get(0);
			if (Math.abs(res) < 1e-6) {
				//System.out.println(0);
              //ResTextField1.setText(0+"");                  
                res=0.0;      
			}
			Function f = new Function();
			result=f.parseFraction(res+"");
			Calculator();
			// ///计算结果出来了！！！！！！！
		} catch (Exception e) {
			//System.out.println("表达式异常");
             String s = "Wrong Expression";

		}
	}
	private static double Calculate(ArrayList<Double> value, String c,
			double num) {// 三角函数的计算(包括平方立方根)
		// TODO Auto-generated method stub
		// 如果遇到左括号，则直接返回当前数，例如"(5)"
		if (c.equals("(")) {
			return num;
		} else if (c.equals("^")) {
			return Math.pow(value.remove(value.size() - 1), num);
		} else if (c.equals("+")) {
			return num + value.remove(value.size() - 1);
		} else if (c.equals("-")) {
			return value.remove(value.size() - 1) - num;
		} else if (c.equals("*")) {
			return value.remove(value.size() - 1) * num;
		} else
			return value.remove(value.size() - 1) / num;

	}
    private static int compare(String a, String b) {// 值为1入栈,a为当前，b为栈顶
		// TODO Auto-generated method stub
		if (a.equals(b) || (a.equals("+") && b.equals("-"))
				|| (a.equals("-") && b.equals("+"))
				|| (a.equals("*") && b.equals("/"))
				|| (a.equals("/") && b.equals("*"))) {
			return 0;
		} else if (b.equals("(")) {
			return 1;
		} else if ((a.equals("*") || a.equals("/") && !b.equals("("))) {
			return 1;
		} else if ((a.equals("*") || a.equals("/"))
				&& (b.equals("+") || b.equals("-"))) {
			return 1;
		} else if (a.equals("^")
				&& (b.equals("+") || b.equals("-") || b.equals("*") || b
						.equals("/"))) {
			return 1;
		} else {
			return 0;
		}
	}
	
}
